package model.elements;

import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import model.collisions.CollisionCategory;
import model.elements.attributes.Coordinate2D;
import model.elements.behaviours.Positionable;
import model.elements.commands.ElementCommand;
import model.elements.commands.ElementCommandFactory;
import model.elements.states.life.Alive;
import model.elements.states.life.Dead;
import model.elements.states.life.ElementLifeState;
import model.exceptions.ModelExceptions;

// TODO: Auto-generated Javadoc
/*
 * Raiz unica para todos los elementos posicionables. 
 * Esto lo hago para restringir la element DB con una Unica raiz.
 * Ademas, todos los elementos posicionables son colisionables y tienen eso en comun.
 */

/**
 * The Class Element2D.
 */
public abstract class Element2D implements Positionable
{

	//protected Identifier 			m_id 	= new Identifier();	// Unique ID
	/** The m_current position. */
	protected Coordinate2D 			m_currentPosition;			// Posicion Actual

	/** The m_life state. */
	protected ElementLifeState 		m_lifeState;
	
	/**
	 * Instantiates a new element2 d.
	 *
	 * @param position the position
	 * @throws ModelExceptions the model exceptions
	 */
	public Element2D(Coordinate2D position) throws ModelExceptions
	{
		m_currentPosition = position;
		ElementCommand command = ElementCommandFactory.getElementDoesNothing();
		m_lifeState = new Alive( command );
		m_uuid = getNewUUID();
	}

	/*
	 // DEPRECATED
	@Override
	public int getId()
	{
	    return m_id.getId();
	}/**/
	
	/**
	 * Checks if is alive.
	 *
	 * @return true, if is alive
	 */
	public boolean isAlive()
	{
	    return m_lifeState.isAlive();
	}

	/**
	 * Kill.
	 *
	 * @throws ModelExceptions the model exceptions
	 */
	public void kill() throws ModelExceptions
	{
		m_lifeState = new Dead();		
	}

	/**
	 * Update.
	 *
	 * @throws ModelExceptions the model exceptions
	 */
	public void update() throws ModelExceptions{};

	/* (non-Javadoc)
	 * @see model.elements.behaviours.Positionable#getPosition()
	 */
	@Override
	public Coordinate2D getPosition()
	{
	    return m_currentPosition;
	}

	/* (non-Javadoc)
	 * @see model.collisions.Collisionable#getCollisionCategory()
	 */
	@Override
	public CollisionCategory getCollisionCategory()
	{
		return m_lifeState.getCategory();
	}

	/** The m_uuid. */
	private long m_uuid;

    /** The m_next uuid. */
    private static long m_nextUUID = 1;

    /**
     * Gets the new uuid.
     *
     * @return the new uuid
     */
    static private long getNewUUID()
    {
        return m_nextUUID++;
    }
    
    /**
     * Gets the uuid.
     *
     * @return the uuid
     */
    private long getUUID()
    {
        return m_uuid;
    }
	
    /**
     * Save.
     *
     * @return the element
     */
    public Element save()
    {
        Element elem = DocumentHelper.createElement( this.getClass().getName() );
        elem.addAttribute( "UUID", this.getUUID()+"" );
        elem.addAttribute( "x", this.getPosition().getRealX()+"" );
        elem.addAttribute( "y", this.getPosition().getRealY()+"" );
        
        return elem;
    }
}
